package crypto;
import java.io.FileReader;
import java.io.FileWriter;
import java.util.*;

public class CryptAnalyzer {
	
	private Vector<Character[][]> potentialPads;
	private Vector<Character[][]> pads;
	private Vector<String> cipherTextList;
	private int messageCount;
	
	public CryptAnalyzer(String cipherFilenameList) {
		potentialPads = new Vector<Character[][]>();
		pads = new Vector<Character[][]>();
		cipherTextList = new Vector<String>();
		messageCount = cipherFilenameList.length() - cipherFilenameList.replaceAll("\\,", "").length();
		
		for (String cipherTextFilename : cipherFilenameList.split(",")) {
			try {
				FileReader fr = new FileReader(cipherTextFilename + ".txt");
				String cipherText = new String();
				Character currentCharacter = new Character((char) fr.read());

				while (currentCharacter.charValue() != -1) {
					cipherText += currentCharacter.toString();
					currentCharacter = new Character((char) fr.read());
				}
				cipherTextList.add(cipherText);
				fr.close();
			} catch (Exception e) {
				System.err.println("ERROR: " + e);
			}
		}
	}
	
	public void retrievePads() {
		/* analyze the results of getPotentialPads, output the real pads
        TODO: 
            * call getPotentialPads()
                for first trial, with just one pad, call getSinglePad()
            * call outputPad() for each item returned from getPotentialPads() or
                getSingle Pad()
        */
	}
	
	public Character[][] getPotentialPads() {
		Character[][] padCandidate = new Character[50][80];
		int currentCharPosition = 0;
		String cipherText;
		char currentChar;
		for (int m = 0; m < 50; m++) {
			for (int n = 0; n < 80; n++) {
				HashMap<Character, Integer> letterCount = new HashMap<Character, Integer>();
				currentCharPosition = m * 50 + n;
				for (int x = 0; x < messageCount; x++) {
					cipherText = cipherTextList.elementAt(x);
					currentChar = cipherText.charAt(currentCharPosition);
					if (letterCount.containsKey(currentChar)) {
						int oldValue = letterCount.get(currentChar).intValue();
						letterCount.remove(currentChar);
						letterCount.put(new Character(currentChar), oldValue + 1);
						
						// sort the dictionary from highest account to lowest account
					} else {
						letterCount.put(new Character(currentChar), 1);
					}
				}
			}
		}
		
		return padCandidate;
	}
	
	public void outputPad(String outputFilename, String pad) {
		String currentDirectory = System.getProperty("user.dir") + "/";
		try {
			FileWriter fw = new FileWriter(currentDirectory + "/" + outputFilename);
			fw.write(pad);
			fw.close();
		} catch (Exception e) {
			System.err.println("ERROR: " + e);
		}
	}
	
	/*
	 p = pad
c = encrypted letter
t = plain text

p = c Mod[95]-t+64
	 * */
	
	public Character getSinglePad(char cipherChar, char plainText) {
		char pad = (char) (cipherChar % 95 - plainText + 64);
		return new Character(pad);
	}
}
